 
/* 
 * Copyright (C) Ignacio Lucas
 */
 
/*
 *  worker, hecho por Ignacio Lucas
 *
 *  Worker que implementa el modelo productor-consumidor, donde cada worker puede poner o tomar tareas de una cola, 
 *  cuyo acceso esta serializado mediante mecanismos de semaforos para evitar race-conditions.
 *
 *  Ignacio Lucas <ignacio.lucas@gmail.com>
 *
 */
#if !defined(WORKER_H)
#define WORKER_H


#include "priority_queue.h"
#include "logger.h"

// estructura asociada a un worker
typedef struct s_worker *worker_t;

// funcion para realizar una operacion de forma exclusiva entre todos los workers.
typedef int (*fn_call_exclusive)(void *arg1, void *arg2);

// inicializacion del modulo de workers.
int worker_init_module();

// destruccion del modulo de worker.
void worker_destroy_module();

// seteo de datos de usuario para el worker en ejecucion.
inline int worker_set_user_data(void *user_data);

// obtencion de datos de usuario.
inline void *worker_get_user_data(void);

// creacion de un worker.
worker_t worker_init(int (*main_worker_job)(void *), void *args, priority_queue_t queue, size_t stack_size, int id);

// arranque del hilo de ejecucion de un worker.
int worker_start(worker_t wkt);

// devuelve el identificador asignado a un worker.
int worker_get_id(worker_t wkt);

// utilidad de log para los workers.
// int worker_log_function(enum LOG_LEVEL log_level, const char *msg, void *param);

// agrega una tarea a la cola
int worker_push_job(worker_t worker, void *job);

// agregar una tarea a la cola con una prioridad especifica.
int worker_push_job_priority(worker_t w_t, void *job, int priority);

// agrega un vector de tareas a la cola
int worker_push_job_vector(worker_t worker, void **jobs, int size);

// agrega un vector de tareas a la cola, todos con una prioridad especifica común.
int worker_push_job_vector_priority(worker_t worker, void **jobs, int size,int priority);

// toma una tarea de la cola, bloqueando al invocador si no hay tareas para entregar.
void *worker_pull_job(worker_t worker);

// similar a worker_pull_job, pero en caso de no haber tareas en la cola, no bloquea al invocador sino que devuelve NULL.
void *worker_pick_job(worker_t worker);

// acceso a un pool de forma sincronizada..
inline int worker_object_pool_put_exclusive(int pool_type, void *p, object_pool *pool);

inline void* worker_object_pool_get_exclusive(int pool_type, object_pool *pool);

//llamada exclusiva de un worker a una funcion de tipo fn_worker_call_exclusive.
inline int worker_call_exclusive(fn_call_exclusive func, void *arg1, void *arg2);

// destruir un worker.
int worker_destroy(worker_t wk);

#endif
